#ifndef __ARP_H
#define __ARP_H

/* This file contains the strucutres, headers and 
 * functions required by the arp module 
 */
#include "unp.h"
#include <sys/types.h>
#include <sys/socket.h>
//#include <netpacket/packet.h>
//#include <net/ethernet.h>
#include <sys/select.h>
#include <errno.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <sys/un.h>
//#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>

#include "hw_addrs.h"
#include "lists.h"

#define ETH_ARP_PROTO 9225
#define DOM_SOCK_FILE "arp_group9.txt"
#define IP_SIZE 4
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ARP_ID 0x922

/* Cache entry */
struct address_cache {
    char    ip_addr[IP_SIZE];     /* IP address */
    char    if_haddr[IF_HADDR];   /* hardware address */
    int     if_index;             /* interface index */
    unsigned short sll_hatype;
    int domain_sockfd;
    struct list_head list_element;
};

struct arp_packet {
    int type;
    short id;
    char sender_mac[IF_HADDR];
    char sender_ip[IP_SIZE];
    char target_mac[IF_HADDR];
    char target_ip[IP_SIZE];
};
    
struct hwaddr {
    int             sll_ifindex;     /* Interface number */
    unsigned short  sll_hatype;      /* Hardware type */
    unsigned char   sll_halen;       /* Length of address */
    unsigned char   sll_addr[6];     /* Physical layer address */
};

void handle_message_on_packet_socket(int packet_sockfd, struct sockaddr_ll *pfaddr);
void handle_message_on_domain_socket(int dom_sockfd, int packet_sockfd, struct sockaddr_ll *pfaddr);
struct address_cache * already_in_cache(char *ip_addr);
void sig_handler(int);
#endif
